﻿Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Text
Imports System.Text.RegularExpressions

Public Class NetworkTools
    'Dim strResult As String = ""
    ReadOnly pingEventHandler As New System.Net.NetworkInformation.PingCompletedEventHandler(AddressOf PingResult)
    Public Function GetHostNameFromIP(ByRef iP As String) As System.Net.IPHostEntry
        Dim host As System.Net.IPHostEntry
        'Dim DNSIp As System.Net.IPHostEntry
        Try
            host = Dns.GetHostEntry(iP)
            'DNSIp = Dns.GetHostEntry(host.HostName)

            Return host
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            'Return ex.Message
        End Try

    End Function
    Public Function IsPingable(ByVal strHost As String) As String

        'Dim result As String = ""
        Dim pingSender As New Ping()
        Dim options As New PingOptions()

        ' Use the default Ttl value which is 128,
        ' but change the fragmentation behavior.
        options.DontFragment = True

        ' Create a buffer of 32 bytes of data to be transmitted.
        Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        Dim buffer() As Byte = Encoding.ASCII.GetBytes(data)
        Dim timeout As Integer = 500

        'ADD EVENT HANDLER FOR THE PING COMPLETED EVENT
        'PingResult IS THE SUB ROUTINE BELOW
        'AddHandler pingSender.PingCompleted, _
        'AddressOf PingResult
        AddHandler pingSender.PingCompleted, _
                   AddressOf PingResult

        'TELL USER WHAT IS BEING PINGED
        Console.WriteLine("Sending Async Request To: " & strHost)

        'SEND ASYNC PING REQUEST
        pingSender.SendAsync(strHost, timeout, buffer, strHost)
        '*********************************************************************************
        '                               Working Ping Code                                '
        '*********************************************************************************
        'Try
        '    Dim reply As PingReply = pingSender.Send(strHost, timeout, buffer, options)
        '    If reply.Status = IPStatus.Success Then

        '        result = reply.Address.ToString
        '    End If
        'Catch ex As Exception
        '    result = ex.InnerException.Message
        'Finally
        'End Try
        'Return result
    End Function
    'THE PING RESULT THAT WILL FIRE WHEN A PING COMPLETES
    Private Sub PingResult(ByVal sender As Object, ByVal e As System.Net.NetworkInformation.PingCompletedEventArgs)

        'OUTPUT TO USER, e.UserState IS WHAT WE PASSED IN AS THE UserToken (ItemToPing) IN THE ABOVE CODE
        Console.WriteLine("")
        Console.WriteLine("***********************************")
        Console.WriteLine("Result is back from: " & e.UserState.ToString)

        'IF THERE WAS AN ERROR THEN OUTPUT INFORMATION ABOUT THE ERROR
        'OTHERWISE OUTPUT INFORMATION ABOUT THE RESULT OF THE PING REQUEST
        'THE EVENTARGS e HAVE A LOT OF INFORMATION IN THE e.Reply VARIABLE
        '
        
        If e.Error IsNot Nothing Then
            Console.WriteLine("Error: " & e.Error.Message)
            If e.Error.InnerException IsNot Nothing Then
                Console.WriteLine("More Info: " & e.Error.InnerException.Message)
                strPResult = e.Error.InnerException.Message
                pingResultTbl.Rows.Add(e.UserState.ToString, e.Error.InnerException.Message)
                'pingResultTbl.Rows.Add(e.Error.InnerException.Message)
                NetGui.ProgressBar1.Increment(1)
            End If
        Else
            Console.WriteLine("Status: " & e.Reply.Status.ToString)
            Console.WriteLine("Round Trip Time: " & e.Reply.RoundtripTime.ToString)
            Console.WriteLine("Response Buffer Length: " & e.Reply.Buffer.Length.ToString)
            Console.WriteLine("Resolved IP Address: " & e.Reply.Address.ToString)
            pingResultTbl.Rows.Add(e.UserState.ToString, e.Reply.Address.ToString)
            strPResult = e.Reply.Address.ToString
            NetGui.ProgressBar1.Increment(1)
        End If
        Console.WriteLine("***********************************")
        Console.WriteLine("")

        'THE SENDER IN THE ARGUMENTS IS THE PING OBJECT THAT WE CREATED
        'SO NOW REMOVE THE EVENT HANDLER LISTENER AS IT IS NO LONGER NEEDED
        'AND CALL Dispose() ON THE PING CLASS TO CLEAN UP UNMANAGED RESOURCES
        With DirectCast(sender, Ping)
            'RemoveHandler .PingCompleted, AddressOf PingResult
            RemoveHandler .PingCompleted, PingEventHandler
            .Dispose()
            pingFinished = True
        End With
    End Sub
    Public Sub BuildTable()
        pingResultTbl.Columns.Add("HostName", GetType(String))
        pingResultTbl.Columns.Add("PIPAddress", GetType(String))
    End Sub
    Public Function IsValidIPAddress(ByVal strIPAddress As String) As Boolean
        On Error GoTo Handler
        Dim varAddress As Object, n As Long, lCount As Long
        varAddress = Split(strIPAddress, ".", , vbTextCompare)
        '//
        If IsArray(varAddress) Then
            For n = LBound(varAddress) To UBound(varAddress)
                lCount = lCount + 1
                varAddress(n) = CByte(varAddress(n))
            Next
            '//
            IsValidIPAddress = (lCount = 4)
        End If
        '//
Handler:
    End Function
    'Function obtained from here http://www.dreamincode.net/forums/topic/25740-vbnet-ip-address-validation/page__view__findpost__p__225462
    Public Function IsIpValid(ByVal ipAddress As String)
        Dim expr As String = "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"
        Dim reg As Regex = New Regex(expr)
        If (reg.IsMatch(ipAddress)) Then
            Dim parts() As String = ipAddress.Split(".")
            If Convert.ToInt32(parts(0)) = 0 Then
                Return False
            ElseIf Convert.ToInt32(parts(3)) = 0 Then
                Return False
            End If
            For i As Integer = 1 To 4
                If i > 255 Then
                    Return False
                End If
            Next
            Return True
        Else
            Return False
        End If
    End Function

End Class
